package com.yaodian100.ec.product.entity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlTransient;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections.comparators.ComparableComparator;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;

import com.yaodian100.core.common.entity.BaseEntity;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.ec.category.entity.Category;
import com.yaodian100.ec.shelf.entity.ViewShelf;
import com.yaodian100.ec.supplierapply.entity.SupplierApply;

@Entity
@Table(name = "EC_PRODUCT_MAIN")
@org.hibernate.annotations.Entity(dynamicUpdate = true)
public class Product extends BaseEntity {
	/**
	 * 商品类型
	 */
	public enum PRODUCT_TYPE {
		MAIN("0"), PREBUY("1"), PRESENT("2"), ADDON("3"), EVENT("4"), QUOTAFILLED("5"), NPICKM("6"), HIGHEND("7");
		String value;

		PRODUCT_TYPE(String i) {
			value = i;
		}

		public String getValue() {
			return value;
		}
	}

	/**
	 * 资料来源
	 */
	public enum DATA_SRC {
		PM("PM"), SUPPLIER("SUPPLIER"), TAOBAO("TAOBAO");
		String value;

		DATA_SRC(String i) {
			value = i;
		}

		public String getValue() {
			return value;
		}
	}

	public enum IS_SCM {
		PO("N"), BO("B"), SCM("Y");
		String value;

		IS_SCM(String i) {
			value = i;
		}

		public String getValue() {
			return value;
		}
	}

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 1467929716541246515L;

	/**
	 * 商品編號
	 */
	@Id
	@Column(name = "PRODUCT_ID", length = 8)
	private String productId;

	/**
	 * 商品名稱
	 */
	@Column(name = "PRODUCT_NAME", nullable = false, length = 500)
	private String productName;

	/**
	 * 商品型態(一般商品,贈品,配件)
	 */
	@Column(name = "PRODUCT_TYPE", nullable = false)
	private int productType;

	/**
	 * 是否為虛擬商品
	 */
	@Column(name = "IS_VIRTUAL", length = 1, nullable = false)
	private String isVirtual;

	/**
	 * 是否售完,default=N
	 */
	@Column(name = "IS_SOLD_OUT", length = 1)
	private String isSoldOut = "N";

	/**
	 * 主目錄編號
	 */
	@Column(name = "MAIN_CATEGORY_ID", nullable = false)
	private int mainCategoryID;

	@XmlTransient
	@NotFound(action = NotFoundAction.IGNORE)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "MAIN_CATEGORY_ID", insertable = false, updatable = false)
	private Category category;

	@XmlTransient
	@NotFound(action = NotFoundAction.IGNORE)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "PRODUCT_ID", referencedColumnName = "PRODUCT_ID", insertable = false, updatable = false)
	private ViewShelf viewShelf;

	/**
	 * @return the viewShelf
	 */
	public ViewShelf getViewShelf() {
		return viewShelf;
	}

	/**
	 * @param viewShelf the viewShelf to set
	 */
	public void setViewShelf(ViewShelf viewShelf) {
		this.viewShelf = viewShelf;
	}

	/**
	 * 主目錄分類路徑
	 */
	@Column(name = "MAIN_CATEGORY_PATH", length = 100)
	private String mainCategoryPath;

	/**
	 * 商品成本
	 */
	@Column(name = "PRODUCT_COST", nullable = false, columnDefinition = "NUMERIC(10, 2)")
	private BigDecimal productCost;

	/**
	 * 廠商建議售價(市價)
	 */
	@Column(name = "LIST_PRICE", nullable = false, columnDefinition = "NUMERIC(10, 2)")
	private BigDecimal listPrice;

	/**
	 * 商品簡介/特色
	 */
	@Column(name = "PRODUCT_BRIEF", length = 50)
	private String productBrief;

	/**
	 * 商品說明
	 */
	@Column(name = "PRODUCT_DESCRIPTION", length = 50)
	private String productDescription;

	/**
	 * 商品規格
	 */
	@Column(name = "PRODUCT_DETAILS", length = 50)
	private String productDetails;

	/**
	 * 购物须知
	 */
	// @Column(name = "PRODUCT_ORDERNOTICE", length = 50)
	@Transient
	private String productOrderNotice;

	/**
	 * 品牌
	 */
	@Column(name = "PRODUCT_BRAND", length = 100)
	private String productBrand;

	/**
	 * 稅率類別
	 */
	@Column(name = "TAX_CLASS", length = 100)
	private String taxClass;

	/**
	 * 是否已刪除,default=N
	 */
	@Column(name = "IS_DELETE", length = 1)
	private String isDelete;

	/**
	 * 長(cm)
	 */
	@Column(name = "PRODUCT_LENGTH", columnDefinition = "NUMERIC(10, 2)")
	private BigDecimal productLength;

	/**
	 * 寬(cm)
	 */
	@Column(name = "PRODUCT_WIDTH", columnDefinition = "NUMERIC(10, 2)")
	private BigDecimal productWidth;

	/**
	 * 高(cm)
	 */
	@Column(name = "PRODUCT_HEIGHT", columnDefinition = "NUMERIC(10, 2)")
	private BigDecimal productHeight;

	/**
	 * 重量(g)
	 */
	@Column(name = "PRODUCT_WEIGHT", columnDefinition = "NUMERIC(10, 2)", nullable = false)
	private BigDecimal productWeight;

	/**
	 * 體積(cm3)
	 */
	@Column(name = "PRODUCT_VOLUME", columnDefinition = "NUMERIC(10, 2)")
	private BigDecimal productVolume;

	/**
	 * 銷售單位(例如件, 個, 罐,...)
	 */
	@Column(name = "PRODUCT_UNIT", length = 10)
	private String productUnit;

	/**
	 * 下單至出貨之前置時間(日),default=1
	 */
	@Column(name = "LEAD_TIME")
	private int leadTime = 1;

	/**
	 * 是否允許超收,default=Y
	 */
	@Column(name = "IS_DELIVER_TOLERANCE", length = 1)
	private String isDeliverTolerance = "Y";

	/**
	 * 最小採購量,default=1
	 */
	@Column(name = "MIN_PO_QUANTITY")
	private int minPOQuantity = 1;

	/**
	 * 最大採購量,default=10
	 */
	@Column(name = "MAX_PO_QUANTITY")
	private int maxPOQuantity = 10;

	/**
	 * 物流倉儲及運送溫層類別 1. 常溫 2. 冷藏 3. 冷凍
	 */
	@Column(name = "TEMPERATURE_TYPE")
	private int temperatureType;

	/**
	 * 退換貨時是否需取回,default=Y
	 */
	@Column(name = "IS_RETURN_PICKUP", length = 1)
	private String isReturnPickup = "Y";

	/**
	 * 此商品可否退換貨,default=Y
	 */
	@Column(name = "IS_RETURNABLE", length = 1)
	private String isReturnable;

	/**
	 * 商品審核狀態,default=PRD250 or PRD400 (依毛利率决定）
	 */
	@Column(name = "PRODUCT_STATUS", length = 6)
	private String productStatus;

	/**
	 * 提供此商品之供應商編號,one to many
	 */
	// @Transient
	@ManyToMany(fetch = FetchType.EAGER, targetEntity = SupplierApply.class)
	@JoinTable(name = "EC_PRODUCT_SUPPLIERAPPLY", joinColumns = @JoinColumn(name = "PRODUCT_ID"), inverseJoinColumns = @JoinColumn(name = "SUPPLIER_ID"))
	@NotFound(action = NotFoundAction.IGNORE)
	private Collection<SupplierApply> suppliers;

	@Column(name = "SUPPLIER_ID", length = 6)
	private String supplierId;

	/**
	 * 主要負責PM
	 */
	@Column(name = "PM_ID", length = 30)
	private String pmID;

	/**
	 * PM所屬單位
	 */
	@Column(name = "ORGANIZATION_PATH", length = 50)
	private String organizationPath;

	/**
	 * 備註
	 */
	@Column(name = "PRODUCT_MEMO", length = 1000)
	private String productMemo;

	/**
	 * 關健字
	 */
	@Column(name = "PRODUCT_KEYWORD", length = 500)
	private String productKeyword;

	@OneToMany(mappedBy = "productId", targetEntity = Specification.class)
	@LazyCollection(LazyCollectionOption.FALSE)
	@Cascade( { CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN })
	@OrderBy("showSeq asc,,specificationId desc")
	private List<Specification> specifications;

	/**
	 * 商品運送限定區域,default 一区
	 */
	@Column(name = "Deliver_Geo_Range", length = 5)
	private String deliverGeoRange = "1";

	/**
	 * 显示顺序(1~9,default 1 ，由小排到大，1最小)
	 */
	@Column(name = "SHOW_SEQ")
	private int showSeq;

	/**
	 * N选M件之M值(即可挑选件数)
	 */
	@Column(name = "PICKUP_QTY")
	private int pickupQty;

	@OneToOne(cascade = javax.persistence.CascadeType.ALL)
	@PrimaryKeyJoinColumn
	private ProductPromotionFlag productPromotionFlag;

	/*
	 * 提报的耀点价（会员价）
	 */
	@Column(name = "PRPS_SHELF_PRICE", columnDefinition = "numeric(10,2)")
	private BigDecimal prpsShelfPrice;

	/**
	 * 预计出货日
	 */
	@Column(name = "EXPECT_SHIP_DATE")
	@Temporal(TemporalType.TIMESTAMP)
	private Date expectShipDate;

	/**
	 * 是否为scm转单 Y:SCM,N:PO,B:BO
	 */
	@Column(name = "IS_SCM", length = 1)
	private String isScm = IS_SCM.PO.getValue();

	/**
	 * 效期管理分类
	 */
	@Column(name = "EXPIRE_MANAGE", length = 4)
	private String expireManage = "EM01";

	/**
	 * 是否需要防拆包材
	 */
	@Column(name = "IS_ANTI_UNPACKING", length = 1)
	private String isAntiUnpacking = "N";

	/**
	 * 长形图/方形图(S:方形圖,R:長形圖)
	 */
	@Column(name = "PRODUCT_GRAPHIC_TYPE", length = 1)
	private String graphicType = "S";

	@Transient
	private String scmNotice;

	/**
	 * 预计到货日
	 */
	@Column(name = "ARRIVAL_DATE")
	@Temporal(TemporalType.TIMESTAMP)
	private Date arrivalDate;

	@Transient
	private boolean isShowArrival;

	/**
	 * 购买时是否需验证码
	 */
	@Column(name = "IS_VALIDATE_NUM", length = 1)
	private String isValidateNum = "N";

	/**
	 * 是否使用"订购后几日出货"?(default N ,Y:是,N:否)
	 */
	@Column(name = "USE_DELIVERY_DAY", length = 1)
	private String useDeliveryDay = "N";

	/**
	 * 订购后几日出货(default 0)
	 */
	@Column(name = "DELIVERY_DAY")
	private int deliveryDay = 0;

	@Transient
	private String approveMemo;

	/**
	 * 旧分类编号
	 */
	@Transient
	private int oldMainCategoryID;

	/**
	 * 台湾馆供应商
	 */
	@Column(name = "TW_SUPPLIER_ID", length = 6)
	private String twSupplierId;

	/**
	 * 是否允許评价尺寸 default N , Y：是，N：否
	 */
	@Column(name = "COMMENT_SIZE", length = 1)
	private String commentSize = "N";

	@Transient
	private Map<String, List<Specification>> specMap;

	/**
	 * 商品分類分身
	 */
	@XmlTransient
	@OneToMany(mappedBy = "productId", targetEntity = ProductCategory.class)
	@LazyCollection(LazyCollectionOption.FALSE)
	@OrderBy("showSeq asc")
	@NotFound(action = NotFoundAction.IGNORE)
	private Collection<ProductCategory> productCategories;

	@XmlTransient
	@OneToMany(mappedBy = "productId", targetEntity = SpecificationMajor.class)
	@LazyCollection(LazyCollectionOption.FALSE)
	@JoinColumn(name = "PRODUCT_ID")
	@OrderBy("showSeq asc")
	// @Where(clause = "IS_DELETE='N'")
	private List<SpecificationMajor> specMajors;

	@Transient
	private Map<String, SpecificationMajor> majorMap;

	/**
	 * 操作步骤,default=1
	 */
	@Column(name = "STEP_FLAG", length = 1)
	private int stepFlag = 1;

	/**
	 * 资料来源,default PM
	 */
	@Column(name = "DATA_SRC", length = 20)
	private String dataSrc = DATA_SRC.PM.getValue();

	/**
	 * 主规格标签
	 */
	@Column(name = "MAIN_CODE_LABEL", length = 10)
	private String mainCodeLabel;

	/**
	 * 次规格标签
	 */
	@Column(name = "SECOND_CODE_LABEL", length = 10)
	private String secondCodeLabel;

	/**
	 * 主规格属性
	 */
	@Column(name = "MAIN_SPEC_NAME", length = 2000)
	private String mainSpecName;

	/**
	 * 次规格属性
	 */
	@Column(name = "SECOND_SPEC_NAME", length = 2000)
	private String secondSpecName;

	/** 熱銷數 */
	@Column(name = "HOTSALE_INVENTORY")
	private int hotSaleInventory = 0;

	/** 暂存-规格列表页的规格状态 */
	@Transient
	private String tmpSepcIsDelete;

	/**
	 * 是否允许COD,default Y
	 */
	@Column(name = "CAN_USE_COD", length = 1)
	private String canUseCod = "Y";

	/**
	 * 自营或是经代销,自營：D(Dealer),經代銷：A(agency)
	 */
	@Column(name = "CHANNEL_FIRM", length = 1)
	private String channelFirm = "A";

	/**
	 * 退换货条件代码 预设:07_15 07_15:7日退/15日换 00_00:不可退不可换 00_15:不可退/15日换 30_30:30日退/30日换
	 */
	@Column(name = "RETURN_RULE", length = 5)
	private String returnRule = "07_15";

	/**
	 * 商品是否限立即购买 预设:N
	 */
	@Column(name = "NM_MUST_ORDER_BUY", length = 1)
	private String nmMustOrderBuy = "N";

	/**
	 * nm搭售商品数量
	 */
	@Transient
	private Map<String, Integer> addOnTypeSize;

	/**
	 * @return the deliverGeoRange
	 */
	public String getDeliverGeoRange() {
		return deliverGeoRange;
	}

	public Date getExpectShipDate() {
		return expectShipDate;
	}

	/**
	 * 若存在上架檔 Y - 已删除 (不可查询,不可销售): 顯示下架 N - 未删除 (可查询,可销售)：正常 Q - 可查询,不可销售(Queryable): 即將銷售 H - 不可查询,可销售(Hidden): 顯示下架
	 * 
	 * 若不存在上架檔: 顯示下架
	 * 
	 * @return the isDelete
	 */
	public String getIsDelete() {
		return isDelete;
	}

	/**
	 * @return the isDeliverTolerance
	 */
	public String getIsDeliverTolerance() {
		return isDeliverTolerance;
	}

	/**
	 * @return the isReturnable
	 */
	public String getIsReturnable() {
		return isReturnable;
	}

	/**
	 * @return the isReturnPickup
	 */
	public String getIsReturnPickup() {
		return isReturnPickup;
	}

	public String getIsScm() {
		return isScm;
	}

	/**
	 * @return the isVirtual
	 */
	public String getIsVirtual() {
		return isVirtual;
	}

	/**
	 * @return the leadTime
	 */
	public int getLeadTime() {
		return leadTime;
	}

	/**
	 * @return the listPrice
	 */
	public BigDecimal getListPrice() {
		return listPrice;
	}

	/**
	 * @return the mainCategoryID
	 */
	public int getMainCategoryID() {
		return mainCategoryID;
	}

	/**
	 * @return the maxPOQuantity
	 */
	public int getMaxPOQuantity() {
		return maxPOQuantity;
	}

	/**
	 * @return the minPOQuantity
	 */
	public int getMinPOQuantity() {
		return minPOQuantity;
	}

	/**
	 * @return the organizationPath
	 */
	public String getOrganizationPath() {
		return organizationPath;
	}

	public int getPickupQty() {
		return pickupQty;
	}

	/**
	 * @return the pmID
	 */
	public String getPmID() {
		return pmID;
	}

	/**
	 * @return the productBrand
	 */
	public String getProductBrand() {
		return productBrand;
	}

	/**
	 * @return the productBrief
	 */
	public String getProductBrief() {
		return productBrief;
	}

	/**
	 * @return the productCost
	 */
	public BigDecimal getProductCost() {
		return productCost;
	}

	/**
	 * @return the productDescription
	 */
	public String getProductDescription() {
		return productDescription;
	}

	/**
	 * @return the productDetails
	 */
	public String getProductDetails() {
		return productDetails;
	}

	/**
	 * @return the productHeight
	 */
	public BigDecimal getProductHeight() {
		return productHeight;
	}

	/**
	 * @return the productId
	 */
	public String getProductId() {
		return productId;
	}

	/**
	 * @return the productKeyword
	 */
	public String getProductKeyword() {
		return productKeyword;
	}

	/**
	 * @return the productLength
	 */
	public BigDecimal getProductLength() {
		return productLength;
	}

	/**
	 * @return the productMemo
	 */
	public String getProductMemo() {
		return productMemo;
	}

	/**
	 * @return the productName
	 */
	public String getProductName() {
		return productName;
	}

	public String getProductOrderNotice() {
		return productOrderNotice;
	}

	public ProductPromotionFlag getProductPromotionFlag() {
		return productPromotionFlag;
	}

	/**
	 * @return the productStatus
	 */
	public String getProductStatus() {
		return productStatus;
	}

	/**
	 * @return the productType
	 */
	public int getProductType() {
		return productType;
	}

	@Transient
	public String getProductTypeStr() {
		return String.valueOf(productType);
	}

	/**
	 * @return the productUnit
	 */
	public String getProductUnit() {
		return productUnit;
	}

	/**
	 * @return the productVolume
	 */
	public BigDecimal getProductVolume() {
		return productVolume;
	}

	/**
	 * @return the productWeight
	 */
	public BigDecimal getProductWeight() {
		return productWeight;
	}

	/**
	 * @return the productWidth
	 */
	public BigDecimal getProductWidth() {
		return productWidth;
	}

	public BigDecimal getPrpsShelfPrice() {
		return prpsShelfPrice;
	}

	public int getShowSeq() {
		return showSeq;
	}

	/**
	 * @return the specifications
	 */
	public List<Specification> getSpecifications() {
		if (specifications == null) {
			specifications = new ArrayList<Specification>();
		}
		return specifications;
	}

	/**
	 * @return the supplierId
	 */
	public String getSupplierId() {
		return supplierId;
	}

	/**
	 * @return the suppliers
	 */
	public Collection<SupplierApply> getSuppliers() {
		if (suppliers == null) {
			suppliers = new ArrayList<SupplierApply>();
		}
		return suppliers;
	}

	/**
	 * @return the taxClass
	 */
	public String getTaxClass() {
		return taxClass;
	}

	/**
	 * @return the temperatureType
	 */
	public int getTemperatureType() {
		return temperatureType;
	}

	/**
	 * @param deliverGeoRange the deliverGeoRange to set
	 */
	public void setDeliverGeoRange(String deliverGeoRange) {
		this.deliverGeoRange = deliverGeoRange;
	}

	public void setExpectShipDate(Date expectShipDate) {
		this.expectShipDate = expectShipDate;
	}

	/**
	 * @param isDelete the isDelete to set
	 */
	public void setIsDelete(String isDelete) {
		this.isDelete = isDelete;
	}

	/**
	 * @param isDeliverTolerance the isDeliverTolerance to set
	 */
	public void setIsDeliverTolerance(String isDeliverTolerance) {
		this.isDeliverTolerance = isDeliverTolerance;
	}

	/**
	 * @param isReturnable the isReturnable to set
	 */
	public void setIsReturnable(String isReturnable) {
		this.isReturnable = isReturnable;
	}

	/**
	 * @param isReturnPickup the isReturnPickup to set
	 */
	public void setIsReturnPickup(String isReturnPickup) {
		this.isReturnPickup = isReturnPickup;
	}

	public void setIsScm(String isScm) {
		this.isScm = isScm;
	}

	/**
	 * @param isVirtual the isVirtual to set
	 */
	public void setIsVirtual(String isVirtual) {
		this.isVirtual = isVirtual;
	}

	/**
	 * @param leadTime the leadTime to set
	 */
	public void setLeadTime(int leadTime) {
		this.leadTime = leadTime;
	}

	/**
	 * @param listPrice the listPrice to set
	 */
	public void setListPrice(BigDecimal listPrice) {
		this.listPrice = listPrice;
	}

	/**
	 * @param mainCategoryID the mainCategoryID to set
	 */
	public void setMainCategoryID(int mainCategoryID) {
		this.mainCategoryID = mainCategoryID;
	}

	/**
	 * @param maxPOQuantity the maxPOQuantity to set
	 */
	public void setMaxPOQuantity(int maxPOQuantity) {
		this.maxPOQuantity = maxPOQuantity;
	}

	/**
	 * @param minPOQuantity the minPOQuantity to set
	 */
	public void setMinPOQuantity(int minPOQuantity) {
		this.minPOQuantity = minPOQuantity;
	}

	/**
	 * @param organizationPath the organizationPath to set
	 */
	public void setOrganizationPath(String organizationPath) {
		this.organizationPath = organizationPath;
	}

	public void setPickupQty(int pickupQty) {
		this.pickupQty = pickupQty;
	}

	/**
	 * @param pmID the pmID to set
	 */
	public void setPmID(String pmID) {
		this.pmID = pmID;
	}

	/**
	 * @param productBrand the productBrand to set
	 */
	public void setProductBrand(String productBrand) {
		this.productBrand = productBrand;
	}

	/**
	 * @param productBrief the productBrief to set
	 */
	public void setProductBrief(String productBrief) {
		this.productBrief = productBrief;
	}

	/**
	 * @param productCost the productCost to set
	 */
	public void setProductCost(BigDecimal productCost) {
		this.productCost = productCost;
	}

	/**
	 * @param productDescription the productDescription to set
	 */
	public void setProductDescription(String productDescription) {
		this.productDescription = productDescription;
	}

	/**
	 * @param productDetails the productDetails to set
	 */
	public void setProductDetails(String productDetails) {
		this.productDetails = productDetails;
	}

	/**
	 * @param productHeight the productHeight to set
	 */
	public void setProductHeight(BigDecimal productHeight) {
		this.productHeight = productHeight;
	}

	/**
	 * @param productId the productId to set
	 */
	public void setProductId(String productId) {
		this.productId = productId;
	}

	/**
	 * @param productKeyword the productKeyword to set
	 */
	public void setProductKeyword(String productKeyword) {
		this.productKeyword = productKeyword;
	}

	/**
	 * @param productLength the productLength to set
	 */
	public void setProductLength(BigDecimal productLength) {
		this.productLength = productLength;
	}

	/**
	 * @param productMemo the productMemo to set
	 */
	public void setProductMemo(String productMemo) {
		this.productMemo = productMemo;
	}

	/**
	 * @param productName the productName to set
	 */
	public void setProductName(String productName) {
		this.productName = productName;
	}

	public void setProductOrderNotice(String productOrderNotice) {
		this.productOrderNotice = productOrderNotice;
	}

	public void setProductPromotionFlag(ProductPromotionFlag productPromotionFlag) {
		this.productPromotionFlag = productPromotionFlag;
	}

	/**
	 * @param productStatus the productStatus to set
	 */
	public void setProductStatus(String productStatus) {
		this.productStatus = productStatus;
	}

	/**
	 * @param productType the productType to set
	 */
	public void setProductType(int productType) {
		this.productType = productType;
	}

	/**
	 * @param productUnit the productUnit to set
	 */
	public void setProductUnit(String productUnit) {
		this.productUnit = productUnit;
	}

	/**
	 * @param productVolume the productVolume to set
	 */
	public void setProductVolume(BigDecimal productVolume) {
		this.productVolume = productVolume;
	}

	/**
	 * @param productWeight the productWeight to set
	 */
	public void setProductWeight(BigDecimal productWeight) {
		this.productWeight = productWeight;
	}

	/**
	 * @param productWidth the productWidth to set
	 */
	public void setProductWidth(BigDecimal productWidth) {
		this.productWidth = productWidth;
	}

	public void setPrpsShelfPrice(BigDecimal prpsShelfPrice) {
		this.prpsShelfPrice = prpsShelfPrice;
	}

	public void setShowSeq(int showSeq) {
		this.showSeq = showSeq;
	}

	/**
	 * @param specifications the specifications to set
	 */
	public void setSpecifications(List<Specification> specifications) {
		this.specifications = specifications;
	}

	/**
	 * @param supplierId the supplierId to set
	 */
	public void setSupplierId(String supplierId) {
		this.supplierId = supplierId;
	}

	/**
	 * @param suppliers the suppliers to set
	 */
	public void setSuppliers(Collection<SupplierApply> suppliers) {
		this.suppliers = suppliers;
	}

	/**
	 * @param taxClass the taxClass to set
	 */
	public void setTaxClass(String taxClass) {
		this.taxClass = taxClass;
	}

	/**
	 * @param temperatureType the temperatureType to set
	 */
	public void setTemperatureType(int temperatureType) {
		this.temperatureType = temperatureType;
	}

	public String getExpireManage() {
		return expireManage;
	}

	public void setExpireManage(String expireManage) {
		this.expireManage = expireManage;
	}

	public String getIsAntiUnpacking() {
		return isAntiUnpacking;
	}

	public void setIsAntiUnpacking(String isAntiUnpacking) {
		this.isAntiUnpacking = isAntiUnpacking;
	}

	public String getGraphicType() {
		return graphicType;
	}

	public void setGraphicType(String graphicType) {
		this.graphicType = graphicType;
	}

	public String getScmNotice() {
		return scmNotice;
	}

	public void setScmNotice(String scmNotice) {
		this.scmNotice = scmNotice;
	}

	public Date getArrivalDate() {
		return arrivalDate;
	}

	public void setArrivalDate(Date arrivalDate) {
		this.arrivalDate = arrivalDate;
	}

	public boolean isShowArrival() {
		isShowArrival = false;
		if (null != arrivalDate) {
			if (DateUtil.getLastTimestamp(0, arrivalDate).getTime() >= DateUtil
					.getLastTimestamp(0, DateUtil.getCurrentTime()).getTime()) {
				isShowArrival = true;
			}
		}
		return isShowArrival;
	}

	public void setShowArrival(boolean isShowArrival) {
		this.isShowArrival = isShowArrival;
	}

	public String getIsValidateNum() {
		return isValidateNum;
	}

	public void setIsValidateNum(String isValidateNum) {
		this.isValidateNum = isValidateNum;
	}

	public String getUseDeliveryDay() {
		return useDeliveryDay;
	}

	public int getDeliveryDay() {
		return deliveryDay;
	}

	public void setUseDeliveryDay(String useDeliveryDay) {
		this.useDeliveryDay = useDeliveryDay;
	}

	public void setDeliveryDay(int deliveryDay) {
		this.deliveryDay = deliveryDay;
	}

	public String getApproveMemo() {
		return approveMemo;
	}

	public void setApproveMemo(String approveMemo) {
		this.approveMemo = approveMemo;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Product [productId=" + productId + ", productName=" + productName + ", productType=" + productType
				+ ", isDelete=" + isDelete + ", pickupQty=" + pickupQty + ", isScm=" + isScm + ", supplierId=" + supplierId
				+ ", modifyUser=" + getModifyUser() + ", modifyDate=" + getModifyDate() + "]";
	}

	public int getOldMainCategoryID() {
		return oldMainCategoryID;
	}

	public void setOldMainCategoryID(int oldMainCategoryID) {
		this.oldMainCategoryID = oldMainCategoryID;
	}

	public Category getCategory() {
		return category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	public String getMainCategoryPath() {
		return mainCategoryPath;
	}

	public void setMainCategoryPath(String mainCategoryPath) {
		this.mainCategoryPath = mainCategoryPath;
	}

	public String getTwSupplierId() {
		return twSupplierId;
	}

	public void setTwSupplierId(String twSupplierId) {
		this.twSupplierId = twSupplierId;
	}

	public Map<String, SpecificationMajor> getMajorMap() {
		Map<String, SpecificationMajor> tmpMajorMap = new LinkedHashMap<String, SpecificationMajor>();
		if (null != specMajors && specMajors.size() > 0) {
			for (SpecificationMajor major : specMajors) {
				tmpMajorMap.put(major.getMainSpecName(), major);
			}
			if (MapUtils.isNotEmpty(this.majorMap)) {
				tmpMajorMap.putAll(this.majorMap);
			}
		} else {// new
			if (MapUtils.isNotEmpty(this.majorMap)) {
				tmpMajorMap.putAll(this.majorMap);
			}
		}
		return tmpMajorMap;
	}

	/**
	 * 新增完后重新sort spec
	 */
	@Transient
	public void sortSpecList() {
		Collections.sort(specifications, new SpecComparator());
	}

	public class SpecComparator extends ComparableComparator {
		/** serialVersionUID */
		private static final long serialVersionUID = -7607399952898993734L;

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.apache.commons.collections.comparators.ComparableComparator#compare(java.lang.Object, java.lang.Object)
		 */
		@Override
		public int compare(Object obj1, Object obj2) {
			if (obj1 instanceof Specification && obj2 instanceof Specification) {
				Specification spec1 = (Specification) obj1;
				Specification spec2 = (Specification) obj2;
				return spec1.getShowSeq() - spec2.getShowSeq();
			} else {
				return super.compare(obj1, obj2);
			}
		}
	}

	public Map<String, List<Specification>> getSpecMap() {
		sortSpecList();
		specMap = new LinkedHashMap<String, List<Specification>>();
		if (null != specifications && specifications.size() > 0) {
			Map<String, String> mainMap = new LinkedHashMap<String, String>();
			for (Specification spec : specifications) {
				mainMap.put(spec.getMainSpecName(), spec.getMainSpecName());
			}
			List<Specification> specLists = null;
			for (String mainSpec : mainMap.keySet()) {
				specLists = new LinkedList<Specification>();
				for (Specification spec : getSpecifications()) {
					if (spec.getMainSpecName().equals(mainSpec)) {
						specLists.add(spec);
					}
				}
				specMap.put(mainSpec, specLists);
			}
		}
		return specMap;
	}

	public int getStepFlag() {
		return stepFlag;
	}

	public String getDataSrc() {
		return dataSrc;
	}

	public String getMainCodeLabel() {
		return mainCodeLabel;
	}

	public String getSecondCodeLabel() {
		return secondCodeLabel;
	}

	public String getMainSpecName() {
		return mainSpecName;
	}

	public String getSecondSpecName() {
		return secondSpecName;
	}

	public void setMajorMap(Map<String, SpecificationMajor> majorMap) {
		this.majorMap = majorMap;
	}

	public void setSpecMap(Map<String, List<Specification>> specMap) {
		this.specMap = specMap;
	}

	public void setStepFlag(int stepFlag) {
		this.stepFlag = stepFlag;
	}

	public void setDataSrc(String dataSrc) {
		this.dataSrc = dataSrc;
	}

	public void setMainCodeLabel(String mainCodeLabel) {
		this.mainCodeLabel = mainCodeLabel;
	}

	public void setSecondCodeLabel(String secondCodeLabel) {
		this.secondCodeLabel = secondCodeLabel;
	}

	public void setMainSpecName(String mainSpecName) {
		this.mainSpecName = mainSpecName;
	}

	public void setSecondSpecName(String secondSpecName) {
		this.secondSpecName = secondSpecName;
	}

	public Collection<ProductCategory> getProductCategories() {
		return productCategories;
	}

	public void setProductCategories(Collection<ProductCategory> productCategories) {
		this.productCategories = productCategories;
	}

	public int getHotSaleInventory() {
		return hotSaleInventory;
	}

	public void setHotSaleInventory(int hotSaleInventory) {
		this.hotSaleInventory = hotSaleInventory;
	}

	public List<SpecificationMajor> getSpecMajors() {
		return specMajors;
	}

	public void setSpecMajors(List<SpecificationMajor> specMajors) {
		this.specMajors = specMajors;
	}

	public String getTmpSepcIsDelete() {
		return tmpSepcIsDelete;
	}

	public void setTmpSepcIsDelete(String tmpSepcIsDelete) {
		this.tmpSepcIsDelete = tmpSepcIsDelete;
	}

	public String getCanUseCod() {
		return canUseCod;
	}

	public void setCanUseCod(String canUseCod) {
		this.canUseCod = canUseCod;
	}

	public String getChannelFirm() {
		return channelFirm;
	}

	public void setChannelFirm(String channelFirm) {
		this.channelFirm = channelFirm;
	}

	public String getReturnRule() {
		return returnRule;
	}

	public void setReturnRule(String returnRule) {
		this.returnRule = returnRule;
	}

	public String getNmMustOrderBuy() {
		return nmMustOrderBuy;
	}

	public void setNmMustOrderBuy(String nmMustOrderBuy) {
		this.nmMustOrderBuy = nmMustOrderBuy;
	}

	/**
	 * 取得可用specMajors
	 * 
	 * @return
	 */
	@Transient
	public List<SpecificationMajor> getActivateSpecMajors() {
		List<SpecificationMajor> aSpecMajors = new ArrayList<SpecificationMajor>();
		if (null != specMajors) {
			for (SpecificationMajor sm : specMajors) {
				if ("N".equals(sm.getIsDelete())) {
					aSpecMajors.add(sm);
				}
			}
		}
		return aSpecMajors;
	}

	public Map<String, Integer> getAddOnTypeSize() {
		return addOnTypeSize;
	}

	public void setAddOnTypeSize(Map<String, Integer> addOnTypeSize) {
		this.addOnTypeSize = addOnTypeSize;
	}

	public String getCommentSize() {
		return commentSize;
	}

	public void setCommentSize(String commentSize) {
		this.commentSize = commentSize;
	}

	public String getIsSoldOut() {
		return isSoldOut;
	}

	public void setIsSoldOut(String isSoldOut) {
		this.isSoldOut = isSoldOut;
	}

}